package com.sharemarking.wa.platform.service.impl;


import com.sharemarking.wa.platform.dto.MicroProgramSession;
import com.sharemarking.wa.platform.exception.MicroProgramSessionExpiredException;
import com.sharemarking.wa.platform.exception.MicroProgramSignatureException;
import com.sharemarking.wa.platform.service.SecurityService;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.util.Random;

@Service
public class SecurityServiceImpl implements SecurityService {
	
	@Autowired
	private HttpServletRequest req;
	
	@Autowired
	private CacheManager cm;
	
	@Override
	public String getToken() {
		Random rd=new Random();
		long r1=rd.nextLong();
		long r2=rd.nextLong();
		long r3=rd.nextLong();
		byte[] randBytes=ByteBuffer.allocate(Long.BYTES*3).putLong(r1).putLong(r2).putLong(r3).array();
		String target= Base64.encodeBase64URLSafeString(randBytes);
		Cache c=cm.getCache("SESSION_KEY");
		return c.get(target)==null?target:getToken();
	}

	@Override
	public Integer getCurrentUserId() {
		String token=req.getParameter("token");
		if(!StringUtils.isEmpty(token)) {
//			if(token.length() < 7) {
//				return Integer.valueOf(token);
//			}
			Cache c=cm.getCache("LOGIN_TOKEN");
			ValueWrapper vw=c.get(token);
			if(vw!=null) {
				c.put(token,(Integer)vw.get());
				return (Integer)vw.get();
			}
		}
		throw new MicroProgramSessionExpiredException();
	}
	
	@Override
	public MicroProgramSession getCurrentProgramSession() {
		String token=req.getParameter("token");
		if(StringUtils.isEmpty(token))return null;
		Cache c=cm.getCache("SESSION_KEY");
		ValueWrapper vw=c.get(token);
		if(vw!=null) {
			c.put(token,(MicroProgramSession)vw.get());
			return (MicroProgramSession)vw.get();
		} else {
			throw new MicroProgramSessionExpiredException();
		}
	} 

	@Override
	public void checkMicroProgramData(String target, String signature) {
		MicroProgramSession session=getCurrentProgramSession();
		if(session!=null) {
			String sessionKey=session.getSessionKey();
//			System.out.println(sha1(target+sessionKey));
//			System.out.println(signature);
			if(target!=null && signature!=null && signature.equals(sha1(target+sessionKey))) return;
		}
		throw new MicroProgramSignatureException();
	}
	
	private final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',  
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 

	private String getFormattedText(byte[] bytes) {  
        int len = bytes.length;  
        StringBuilder buf = new StringBuilder(len * 2);  
        // 把密文转换成十六进制的字符串形式  
        for (int j = 0; j < len; j++) {  
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);  
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);  
        }  
        return buf.toString();  
    }
	
	public String sha1(String str) {  
        if (str == null) {  
            return null;  
        }  
        try {  
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");  
            messageDigest.update(str.getBytes());  
            return getFormattedText(messageDigest.digest());  
        } catch (Exception e) {
            throw new RuntimeException(e);  
        }  
    }

}
